#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<string.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <limits.h>
#include<time.h>
char paths[1000],patht[1000],temp_paths[1000],temp_patht[1000];
void Copy(char *spathname,char *tpathname)
{
   int sfd,tfd;
   struct stat s,t;
   char c;
   sfd=open(spathname,O_RDONLY);
   tfd=open(tpathname,O_RDWR|O_CREAT);
   while(read(sfd,&c,1)>0)
        write(tfd,&c,1);
   fstat(sfd,&s);
   chown(tpathname,s.st_uid,s.st_gid);
   chmod(tpathname,s.st_mode);
   
   close(sfd);
   close(tfd);
}

void d_copy(char *spathname,char *tpathname)
{
   struct stat s,t,temp_s,temp_t;
   struct dirent *s_p;
   DIR *dirs,*dirt;
   
   stat(spathname,&s);
   mkdir(tpathname,s.st_mode);
   chown(tpathname,s.st_uid,s.st_gid);
   dirt=opendir(tpathname);
   dirs=opendir(spathname);
   strcpy(temp_paths,spathname);
   strcpy(temp_patht,tpathname);
   while((s_p=readdir(dirs))!=NULL)
   {
      if(strcmp(s_p->d_name,".")!=0&&strcmp(s_p->d_name,"..")!=0)
      {
          strcat(temp_paths,"/");
          strcat(temp_paths,s_p->d_name);
          strcat(temp_patht,"/");
          strcat(temp_patht,s_p->d_name);
          lstat(temp_paths,&s);
          temp_s.st_mode=s.st_mode;
          if(S_ISLNK(temp_s.st_mode))
          {
              printf("%s 是一个符号链接文件\n",temp_paths);
          }
          else if(S_ISREG(temp_s.st_mode))
          {
              printf("拷贝文件 %s ......\n",temp_paths);
              Copy(temp_paths,temp_patht);
              strcpy(temp_paths,spathname);
              strcpy(temp_patht,tpathname);
          }
          else if(S_ISDIR(temp_s.st_mode))
          {
              printf("复制目录 %s ......\n",temp_paths);
              d_copy(temp_paths,temp_patht);
              strcpy(temp_paths,spathname);
              strcpy(temp_patht,tpathname);
          }
      }
   }
}
//判断是否为目录
bool is_dir(const char *path)
{
    struct stat statbuf;
    if(lstat(path, &statbuf) ==0)//lstat返回文件的信息，文件信息存放在stat结构中
    {
        return S_ISDIR(statbuf.st_mode) != 0;//S_ISDIR宏，判断文件类型是否为目录
    }
    return false;
}

//判断是否为常规文件
bool is_file(const char *path)
{
    struct stat statbuf;
    if(lstat(path, &statbuf) ==0)
        return S_ISREG(statbuf.st_mode) != 0;//判断文件是否为常规文件
    return false;
}

//判断是否是特殊目录
bool is_special_dir(const char *path)
{
    return strcmp(path, ".") == 0 || strcmp(path, "..") == 0;
}

//生成完整的文件路径
void get_file_path(const char *path, const char *file_name,  char *file_path)
{
    strcpy(file_path, path);
    if(file_path[strlen(path) - 1] != '/')
        strcat(file_path, "/");
    strcat(file_path, file_name);
}

void delete_file(const char *path)
{
    DIR *dir;
    struct dirent *dir_info;
    char file_path[PATH_MAX];
    if(is_file(path))
    {
        remove(path);
        return;
    }
    if(is_dir(path))
    {
        if((dir = opendir(path)) == NULL)
            return;
        while((dir_info = readdir(dir)) != NULL)
        {
            get_file_path(path, dir_info->d_name, file_path);
            if(is_special_dir(dir_info->d_name))
                continue;
            delete_file(file_path);
            rmdir(file_path);
        }
    }
}

int main()
{
   int i=0;
   struct dirent *sp,*tp;
   char spath[1000],tpath[1000],temp_spath[1000],temp_tpath[1000],twopath[1000],temp_twospath[1000];
   struct stat sbuf,tbuf,temp_sbuf,temp_tbuf;
   char sdirect[1000],tdirect[1000],sdirect1[1000],judge;
   char choose[1000]; 
   DIR *dir_s,*dir_t,*twodir_t;
   printf("欢迎使用本系统\t\t\t\n");
   printf("请输入源目录的路径和名称 :");
   scanf("%s",sdirect);
   dir_s=opendir(sdirect);
   if(dir_s==NULL)
   {
      printf("This directory don't exist !\n");
      return 0;
   }
   if(stat(sdirect,&sbuf)!=0)
   {
      printf("Get status error !\n");
      return 0;
   }
   printf("请输入目标目录的路径和名称 :");
   scanf("%s",tdirect);
   dir_t=opendir(tdirect);
   if(dir_t==NULL)
   {
      mkdir(tdirect,sbuf.st_mode);
      chown(tdirect,sbuf.st_uid,sbuf.st_gid);
      dir_t=opendir(tdirect);
   }
   else
   {
      chmod(tdirect,sbuf.st_mode);
      chown(tdirect,sbuf.st_uid,sbuf.st_gid);
   }
   printf("1:备份A到B\t\t\n");
   printf("2:将B同步到A\t\t\n");
   printf("3:将A同步到B\t\t\n");
   printf("4:将AB同时同步（取并集）到C\t\t\n");
   printf("请输入的你的选择\t\t\n");
   scanf("%s",choose);
   if(strcmp(choose,"1")==0)
   {
   strcpy(spath,sdirect);
   strcpy(tpath,tdirect);
   strcpy(temp_spath,sdirect);
   strcpy(temp_tpath,tdirect);
   printf("开始复制......\n");
   while((sp=readdir(dir_s))!=NULL)
   {
      if(strcmp(sp->d_name,".")!=0&&strcmp(sp->d_name,"..")!=0)
      {
          strcat(temp_spath,"/");
          strcat(temp_spath,sp->d_name);
          strcat(temp_tpath,"/");
          strcat(temp_tpath,sp->d_name);
          lstat(temp_spath,&sbuf);
          temp_sbuf.st_mode=sbuf.st_mode;
          if(S_ISLNK(temp_sbuf.st_mode))
          {
              printf("%s 是一个符号链接文件\n",temp_spath);
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFREG)
          {
            for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              Copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFDIR)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("复制目录 %s ......\n",temp_spath);
              d_copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
               }
          }
      }
   }
   printf("复制结束!\n");
	}
   if(strcmp(choose,"2")==0)
   {
   delete_file(sdirect);
   strcpy(spath,tdirect);
   strcpy(tpath,sdirect);
   strcpy(temp_spath,tdirect);
   strcpy(temp_tpath,sdirect);
   printf("开始复制 ........\n");
   while((sp=readdir(dir_t))!=NULL)
   {
      if(strcmp(sp->d_name,".")!=0&&strcmp(sp->d_name,"..")!=0)
      {
          strcat(temp_spath,"/");
          strcat(temp_spath,sp->d_name);
          strcat(temp_tpath,"/");
          strcat(temp_tpath,sp->d_name);
          lstat(temp_spath,&sbuf);
          temp_sbuf.st_mode=sbuf.st_mode;
          if(S_ISLNK(temp_sbuf.st_mode))
          {
              printf("%s is a symbolic link file\n",temp_spath);
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFREG)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("拷贝文件 %s ......\n",temp_spath);
              Copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFDIR)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("复制目录 %s ......\n",temp_spath);
              d_copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
      }
   }
   printf("复制结束 !\n");
	}
   if(strcmp(choose,"3")==0)
       {
	  delete_file(tdirect);
          strcpy(spath,sdirect);
          strcpy(tpath,tdirect);
          strcpy(temp_spath,sdirect);
          strcpy(temp_tpath,tdirect);
          printf("开始复制 ........\n");
   while((sp=readdir(dir_s))!=NULL)
   {
      if(strcmp(sp->d_name,".")!=0&&strcmp(sp->d_name,"..")!=0)
      {
          strcat(temp_spath,"/");
          strcat(temp_spath,sp->d_name);
          strcat(temp_tpath,"/");
          strcat(temp_tpath,sp->d_name);
          lstat(temp_spath,&sbuf);
          temp_sbuf.st_mode=sbuf.st_mode;
          if(S_ISLNK(temp_sbuf.st_mode))
          {
              printf("%s is a symbolic link file\n",temp_spath);
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFREG)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("拷贝文件 %s ......\n",temp_spath);
              Copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFDIR)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("复制目录 %s ......\n",temp_spath);
              d_copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
      }
   }
   printf("复制结束 !\n");
	}
if(strcmp(choose,"4")==0)
   {
   strcpy(spath,sdirect);
   strcpy(tpath,tdirect);
   strcpy(temp_spath,sdirect);
   strcpy(temp_tpath,tdirect);
   printf("开始复制......\n");
   while((sp=readdir(dir_s))!=NULL)
   {
      if(strcmp(sp->d_name,".")!=0&&strcmp(sp->d_name,"..")!=0)
      {
          strcat(temp_spath,"/");
          strcat(temp_spath,sp->d_name);
          strcat(temp_tpath,"/");
          strcat(temp_tpath,sp->d_name);
          lstat(temp_spath,&sbuf);
          temp_sbuf.st_mode=sbuf.st_mode;
          if(S_ISLNK(temp_sbuf.st_mode))
          {
              printf("%s 是一个符号链接文件\n",temp_spath);
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFREG)
          {
            for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              Copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
              }
          }
          else if((S_IFMT&temp_sbuf.st_mode)==S_IFDIR)
          {
              for(i=0;i<=100;i+=50)
              {
              printf("拷贝文件 %s ......[%3d%%]\r",temp_spath,i);
              sleep(1);
              fflush(stdout);
              printf("复制目录 %s ......\n",temp_spath);
              d_copy(temp_spath,temp_tpath);
              strcpy(temp_tpath,tpath);
              strcpy(temp_spath,spath);
              FILE *fps = fopen("./copy.log","a+");
	      time_t rawtime;
	      struct tm *timeinfo;
              time(&rawtime);
	      timeinfo = localtime(&rawtime);
	      fprintf(fps,"\007The current date/time is:%s\n",asctime(timeinfo));
	      fprintf(fps,"backup directory %s --> %s\n",sdirect, tdirect);
	      fclose(fps);
               }
          }
      }
   }
//删除同名文件

   printf("复制结束!\n");
}
   closedir(dir_t);
   closedir(dir_s);
   return 1;
}
